#include <vector>
#include <algorithm>
#include <unordered_map>
using namespace std;
class Solution
{
public:
    // 时间超限
    int longestArithSeqLength(vector<int> &nums)
    {
        vector<vector<int>> dp(nums.size(), vector<int>(nums.size(), 2));
        unordered_map<int, vector<int>> u_map;
        for (int i = 0; i < nums.size(); i++)
            u_map[nums[i]].push_back(i);
        int ans = 2;
        for (int i = 2; i < nums.size(); i++)
        {
            for (int j = 1; j < i; j++)
            {
                int k = 2 * nums[j] - nums[i];
                if (u_map.count(k))
                    for (auto e : u_map[k])
                        if (e < j)
                            dp[j][i] = dp[e][j] + 1;
                ans = max(ans, dp[j][i]);
            }
        }
        return ans;
    }
    int longestArithSeqLength(vector<int> &nums)
    {
        // 单状态无法推出,因为只知道前一个数结尾的长度不能推出这个的长度
        // dp[j][i]以ji结尾的子序列最大长度 dp[j][i]=dp[k][j]+1
        // k=2*nums[j]-nums[i] 可能不存在
        // 子序列 只看最近的倒数第三个数即可所以
        // 先枚举倒数第二个再枚举倒数第一个可以优化 umap<int,vector>-><int,int>
        vector<vector<int>> dp(nums.size(), vector<int>(nums.size(), 2));
        unordered_map<int, int> u_map;
        u_map[nums[0]] = 0;
        int ans = 2;
        for (int j = 1; j < nums.size(); j++)
        {
            for (int i = j + 1; i < nums.size(); i++)
            {
                int k = 2 * nums[j] - nums[i];
                if (u_map.count(k))
                    dp[j][i] = dp[u_map[k]][j] + 1;
                ans = max(ans, dp[j][i]);
            }
            u_map[nums[j]] = j;
        }
        return ans;
    }
};